"""
命令生成器 - 基于 Linus 设计哲学
简单胜过复杂 - 将简单参数转换为 granian 命令
"""

import os
import shlex
from typing import List, Dict, Any, Optional


class CommandGenerator:
    """命令生成器 - 将简单配置转换为 granian 命令"""
    
    def __init__(self):
        # 固定配置 - Gua CLI 专注于 Gua 框架
        self.fixed_interface = "asginl"  # asgi with Lifespan
    
    def generate_granian_command(
        self,
        app: str,
        config: Dict[str, Any],
        static_dir: Optional[str] = None,
        static_route: str = "/static",
        extra_args: List[str] = None
    ) -> List[str]:
        """生成 granian 命令
        
        Args:
            app: 应用标识符，如 "app:app"
            config: 配置字典
            static_dir: 静态文件目录
            static_route: 静态文件路由前缀
            extra_args: 额外的 granian 参数
            
        Returns:
            granian 命令参数列表
        """
        cmd = ["granian", app]
        
        # 添加固定接口参数
        cmd.extend(["--interface", self.fixed_interface])
        
        # 添加基本参数
        if "host" in config:
            cmd.extend(["--host", str(config["host"])])
        
        if "port" in config:
            cmd.extend(["--port", str(config["port"])])
        
        if "workers" in config:
            cmd.extend(["--workers", str(config["workers"])])
        
        # 添加 reload 参数
        if config.get("reload", False):
            cmd.append("--reload")
        
        # 添加静态文件参数
        if static_dir:
            cmd.extend([
                "--static-path-mount", static_dir,
                "--static-path-route", static_route
            ])
        
        # 添加额外参数
        if extra_args:
            cmd.extend(extra_args)
        
        return cmd
    
    def add_static_args(
        self,
        cmd: List[str],
        static_dir: str,
        static_route: str = "/static"
    ) -> List[str]:
        """添加静态文件参数到命令
        
        Args:
            cmd: 现有命令列表
            static_dir: 静态文件目录
            static_route: 静态文件路由前缀
            
        Returns:
            更新后的命令列表
        """
        # 创建新列表避免修改原列表
        new_cmd = cmd.copy()
        
        new_cmd.extend([
            "--static-path-mount", static_dir,
            "--static-path-route", static_route
        ])
        
        return new_cmd
    
    def format_command_for_display(self, cmd: List[str]) -> str:
        """格式化命令用于显示
        
        Args:
            cmd: 命令参数列表
            
        Returns:
            格式化的命令字符串
        """
        return " ".join(shlex.quote(arg) for arg in cmd)
    
    def validate_app_format(self, app: str) -> bool:
        """验证应用格式
        
        Args:
            app: 应用标识符
            
        Returns:
            是否有效
        """
        if not app:
            return False
        
        # 基本格式检查: module:callable
        if ":" not in app:
            return False
        
        module, callable_name = app.split(":", 1)
        
        # 检查模块名和可调用对象名
        if not module or not callable_name:
            return False
        
        # 检查是否包含有效字符
        import re
        module_pattern = r'^[a-zA-Z_][a-zA-Z0-9_]*(\.[a-zA-Z_][a-zA-Z0-9_]*)*$'
        callable_pattern = r'^[a-zA-Z_][a-zA-Z0-9_]*$'
        
        return (bool(re.match(module_pattern, module)) and
                bool(re.match(callable_pattern, callable_name)))
    
    def detect_app_from_context(self) -> Optional[str]:
        """从当前上下文检测应用
        
        Returns:
            检测到的应用标识符，如果无法检测则返回 None
        """
        # 检查当前目录是否有 app.py
        if os.path.exists("app.py"):
            return "app:app"
        
        # 检查是否有 main.py
        if os.path.exists("main.py"):
            return "main:app"
        
        # 检查 examples 目录
        if os.path.exists("examples") and os.path.isdir("examples"):
            # 列出 examples 目录中的 Python 文件
            examples = []
            for file in os.listdir("examples"):
                if file.endswith(".py") and not file.startswith("_"):
                    examples.append(f"examples.{file[:-3]}:app")
            
            if examples:
                # 返回第一个找到的示例
                return examples[0]
        
        return None